package cn.maihe.elg.operation.centers.hymake.handler.service;

import cn.maihe.elg.operation.centers.hymake.config.HyMakeInfoConfig;
import cn.maihe.elg.operation.centers.hymake.dto.HyMakeBaseRespDTO;
import cn.maihe.elg.operation.centers.hymake.dto.handler.FilePushReqDTO;
import cn.maihe.elg.operation.centers.hymake.handler.HyMakeCenterTradeService;
import cn.maihe.elg.operation.centers.supports.CenterTradeContext;
import cn.maihe.elg.operation.centers.supports.annotation.CenterTradeService;
import cn.maihe.elg.operation.common.Constants;
import cn.maihe.elg.operation.config.ImageUploadConfig;
import cn.maihe.elg.operation.model.enums.*;
import cn.maihe.elg.operation.repository.entity.AcceptOrderInfoDO;
import cn.maihe.elg.operation.repository.entity.BidCustomerDO;
import cn.maihe.elg.operation.repository.entity.CustomerAttachmentDO;
import cn.maihe.elg.operation.repository.entity.GuaranteeAttachmentInfoDO;
import cn.maihe.elg.operation.service.business.BidCustomerService;
import cn.maihe.elg.operation.service.business.CustomerAttachmentService;
import cn.maihe.elg.operation.service.order.AcceptOrderInfoService;
import cn.maihe.elg.operation.service.order.GuaranteeAttachmentInfoService;
import cn.maihe.elg.operation.supports.system.ElgResourceService;
import cn.maihe.elg.operation.utils.IdGenerate;
import lombok.extern.slf4j.Slf4j;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import javax.annotation.Resource;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.List;
import java.util.UUID;

/**
 * @Description 电子保函平台向出函机构（保险公司/银行）推送投保材料的下载地址
 * 文件类型名称 固定但不保证顺序
 * 投保材料
 * 电子申请单
 * 营业执照
 * 企业资质
 * 身份证正面
 * 身份证反面
 * @Author WJH
 * @Date 2022/04/01
 */
@CenterTradeService(
        provider = CenterProviderEnum.HYMAKE,
        centerNo = CenterNoEnum.NINGDE,
        tradeType = TradeType.filePush,
        reqClass = FilePushReqDTO.class,
        respClass = HyMakeBaseRespDTO.class
)
@Slf4j
public class HyMakeFilePushService extends HyMakeCenterTradeService<FilePushReqDTO, HyMakeBaseRespDTO> {

    @Resource
    private ElgResourceService elgResourceService;
    @Resource
    private AcceptOrderInfoService acceptOrderInfoService;
    @Resource
    private CustomerAttachmentService customerAttachmentService;
    @Resource
    private GuaranteeAttachmentInfoService guaranteeAttachmentInfoService;
    @Resource
    private ImageUploadConfig imageUploadConfig;
    @Resource
    private BidCustomerService bidCustomerService;

    public HyMakeFilePushService(HyMakeInfoConfig centerInfosConfig) {
        super(centerInfosConfig);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public HyMakeBaseRespDTO processService(CenterTradeContext<FilePushReqDTO, HyMakeBaseRespDTO> context) {
        FilePushReqDTO req = context.getReq();
        String acceptOrderNo = req.getInsuranceNo();

        AcceptOrderInfoDO acceptOrderInfo = acceptOrderInfoService.getByAcceptOrderNo(acceptOrderNo);
        Assert.notNull(acceptOrderInfo, "查无此投保单号");

        if (AcceptOrderStatus.WAIT_SUBMIT_FIRST_TRAIL.getStatus() != acceptOrderInfo.getStatus()&&
                AcceptOrderStatus.WAIT_SUBMIT_TUNE_UP.getStatus() != acceptOrderInfo.getStatus()) {
            throw new RuntimeException("投保单号非承保已受理状态,无法推送投保材料地址");
        }

        List<FilePushReqDTO.FileInfo> list = req.getFileList();
        list.stream().forEach(fileInfo -> {
            try {
                this.downloadFile(acceptOrderInfo, fileInfo);
            } catch (Exception e) {
                log.error("下载保存推送材料失败：{}", e.getMessage(), e);
                throw new RuntimeException("下载保存推送材料失败：" + e.getMessage(), e);
            }
        });

//        AcceptOrderInfoDO update = AcceptOrderInfoDO.builder().id(acceptOrderInfo.getId())
//                .status(AcceptOrderStatus.WAIT_SUBMIT_TUNE_UP.getStatus()).remark("投保材料地址推送处理成功，待支付地址获取及支付")
//                .build();

        AcceptOrderInfoDO update = AcceptOrderInfoDO.builder().id(acceptOrderInfo.getId())
                .status(AcceptOrderStatus.WAIT_PAY_CONFIRM.getStatus()).remark("投保材料地址推送处理成功，无需获取支付地址，状态更新未待支付确认")
                .build();
        acceptOrderInfoService.updateById(update);

        BidCustomerDO bidCustomer = new BidCustomerDO();
        bidCustomer.setId(acceptOrderInfo.getBidCustomerId());
        bidCustomer.setStatus(BidCustomerStatus.NORMAL.getStatus());
        bidCustomerService.updateById(bidCustomer);


        return HyMakeBaseRespDTO.success("投保材料地址推送处理成功");
    }

    private void downloadFile(AcceptOrderInfoDO acceptOrderInfo, FilePushReqDTO.FileInfo fileInfo) throws Exception {
        String fileTypeName = fileInfo.getFileTypeName();
        AttachmentFileType attachmentFileType = FileTypeNameEnum.toGuaranteeAttachmentFileType(fileTypeName);
        CustomerAttachmentTypeEnum customerAttachmentTypeEnum = FileTypeNameEnum.toCustomerAttachmentFileType(fileTypeName);
        if (attachmentFileType != null) {
            this.saveOrUpdateGuaranteeAttachInfo(attachmentFileType, acceptOrderInfo, fileInfo);
        } else if (customerAttachmentTypeEnum != null) {
            this.saveOrUpdateCustomerAttachInfo(customerAttachmentTypeEnum, acceptOrderInfo, fileInfo);
        }

    }

    private void saveOrUpdateCustomerAttachInfo(CustomerAttachmentTypeEnum customerAttachmentType, AcceptOrderInfoDO acceptOrderInfo, FilePushReqDTO.FileInfo fileInfo) throws Exception {
        String fileUrl = fileInfo.getUrl();
        String md5Value = fileInfo.getMd5Value();
        Long bidCustomerId = acceptOrderInfo.getBidCustomerId();
        CustomerAttachmentDO customerAttachment = customerAttachmentService.getCustomerAttachment(bidCustomerId, customerAttachmentType);
        if (customerAttachment == null) {
            Path tmpPath = elgResourceService.downloadByURL(fileUrl);
//            String relativePath = elgResourceService.transferAndSaveFile(tmpPath, "ofd", bidCustomerId.toString(), fileInfo.getFileTypeName());
            String relativePath = UUID.randomUUID().toString() + "." + elgResourceService.getFileType(tmpPath);
            Path registerDir = Paths.get(imageUploadConfig.getPath(), Constants.REGIST_IMAGE_PATH);
            if(Files.notExists(registerDir)){
                Files.createDirectories(registerDir);
            }
            Path registerImg = registerDir.resolve(relativePath);
            Files.copy(tmpPath, registerImg, StandardCopyOption.REPLACE_EXISTING);

            Files.deleteIfExists(tmpPath);

            customerAttachment = new CustomerAttachmentDO();
            customerAttachment.setId(IdGenerate.getId());
            customerAttachment.setBidderId(bidCustomerId);
            customerAttachment.setAttachType(customerAttachmentType.getType());
            customerAttachment.setAttachPath(relativePath);
            customerAttachment.setAttachFileName(relativePath);
            customerAttachment.setFileMd5(fileInfo.getMd5Value());
            customerAttachment.setFileUrl(fileUrl);

            customerAttachmentService.insert(customerAttachment);
        } else if (!md5Value.equalsIgnoreCase(customerAttachment.getFileMd5())) {
            Path tmpPath = elgResourceService.downloadByURL(fileUrl);
//            String relativePath = elgResourceService.transferAndSaveFile(tmpPath, "ofd", bidCustomerId.toString(), fileInfo.getFileTypeName());
            String relativePath = UUID.randomUUID().toString() + "." + elgResourceService.getFileType(tmpPath);
            Path registerDir = Paths.get(imageUploadConfig.getPath(), Constants.REGIST_IMAGE_PATH);
            if(Files.notExists(registerDir)){
                Files.createDirectories(registerDir);
            }
            Path registerImg = registerDir.resolve(relativePath);
            Files.copy(tmpPath, registerImg, StandardCopyOption.REPLACE_EXISTING);

            Files.deleteIfExists(tmpPath);


            customerAttachment.setBidderId(bidCustomerId);
            customerAttachment.setAttachType(customerAttachmentType.getType());
            customerAttachment.setAttachPath(relativePath);
            customerAttachment.setAttachFileName(relativePath);
            customerAttachment.setFileMd5(fileInfo.getMd5Value());
            customerAttachment.setFileUrl(fileUrl);

            customerAttachmentService.updateById(customerAttachment);
        }

    }

    private void saveOrUpdateGuaranteeAttachInfo(AttachmentFileType attachmentFileType, AcceptOrderInfoDO acceptOrderInfo, FilePushReqDTO.FileInfo fileInfo) throws Exception {
        String fileUrl = fileInfo.getUrl();
        String md5Value = fileInfo.getMd5Value();
        String acceptOrderNo = acceptOrderInfo.getAcceptOrderNo();
        GuaranteeAttachmentInfoDO guaranteeAttachmentInfo = guaranteeAttachmentInfoService.getTypeAttachmentByAcceptOrderNo(acceptOrderNo, attachmentFileType);
        if (guaranteeAttachmentInfo == null) {
            Path tmpPath = elgResourceService.downloadByURL(fileUrl);
            String relativePath = elgResourceService.transferAndSaveFile(tmpPath, "ofd", acceptOrderNo, fileInfo.getFileTypeName());
            Files.deleteIfExists(tmpPath);

            guaranteeAttachmentInfo = new GuaranteeAttachmentInfoDO();
            guaranteeAttachmentInfo.setId(IdGenerate.getId());
            guaranteeAttachmentInfo.setCenterId(acceptOrderInfo.getCenterId());
            guaranteeAttachmentInfo.setOrgId(acceptOrderInfo.getOrgId());
            guaranteeAttachmentInfo.setAcceptOrderNo(acceptOrderInfo.getAcceptOrderNo());
            guaranteeAttachmentInfo.setType(attachmentFileType.getType());
            guaranteeAttachmentInfo.setFileName(fileInfo.getFileTypeName());
            guaranteeAttachmentInfo.setFileType(fileInfo.getFileType());
            guaranteeAttachmentInfo.setFileMd5(fileInfo.getMd5Value());
            guaranteeAttachmentInfo.setFilePath(relativePath);
            guaranteeAttachmentInfo.setRemark("新增" + attachmentFileType.getDesc());
            guaranteeAttachmentInfo.setFileUrl(fileInfo.getUrl());

            guaranteeAttachmentInfoService.insert(guaranteeAttachmentInfo);
        } else if (!md5Value.equalsIgnoreCase(guaranteeAttachmentInfo.getFileMd5())) {
            Path tmpPath = elgResourceService.downloadByURL(fileUrl);
            String relativePath = elgResourceService.transferAndSaveFile(tmpPath, "ofd", acceptOrderNo, fileInfo.getFileTypeName());
            Files.deleteIfExists(tmpPath);

            guaranteeAttachmentInfo.setCenterId(acceptOrderInfo.getCenterId());
            guaranteeAttachmentInfo.setOrgId(acceptOrderInfo.getOrgId());
            guaranteeAttachmentInfo.setAcceptOrderNo(acceptOrderInfo.getAcceptOrderNo());
            guaranteeAttachmentInfo.setType(attachmentFileType.getType());
            guaranteeAttachmentInfo.setFileName(fileInfo.getFileTypeName());
            guaranteeAttachmentInfo.setFileType(fileInfo.getFileType());
            guaranteeAttachmentInfo.setFileMd5(fileInfo.getMd5Value());
            guaranteeAttachmentInfo.setFilePath(relativePath);
            guaranteeAttachmentInfo.setRemark("更新" + attachmentFileType.getDesc());
            guaranteeAttachmentInfo.setFileUrl(fileInfo.getUrl());

            guaranteeAttachmentInfoService.updateById(guaranteeAttachmentInfo);
        }

    }


    public static enum FileTypeNameEnum {
        TYPE01("投保材料"),
        TYPE02("电子申请单"),
        TYPE03("营业执照"),
//        TYPE04("企业资质"),
        TYPE04("资质证书"),
        TYPE05("身份证正面"),
        TYPE06("身份证反面"),
        TYPE15("电子申请单原文件"),
        ;

        FileTypeNameEnum(String fileTypeName) {
            this.fileTypeName = fileTypeName;
        }

        private String fileTypeName;

        public String getFileTypeName() {
            return fileTypeName;
        }

        /**
         * 是否保存到订单附件表
         */
        public static AttachmentFileType toGuaranteeAttachmentFileType(String fileTypeName) {
            if (TYPE01.fileTypeName.equals(fileTypeName)) {
                //投保材料
                return AttachmentFileType.TYPE_13;
            } else if (TYPE02.fileTypeName.equals(fileTypeName)) {
                //申请书pdf文件 客户已签章推送
                return AttachmentFileType.TYPE_11;
            }
            else if (TYPE15.fileTypeName.equals(fileTypeName)) {
                //申请书文件edc 客户已签章推送
                return AttachmentFileType.TYPE_15;
            }
            return null;
        }

        /**
         * 是否保存到订单附件表
         */
        public static CustomerAttachmentTypeEnum toCustomerAttachmentFileType(String fileTypeName) {
            if (TYPE03.fileTypeName.equals(fileTypeName)) {
                return CustomerAttachmentTypeEnum.TYPE_0;
            } else if (TYPE04.fileTypeName.equals(fileTypeName)) {
                return CustomerAttachmentTypeEnum.TYPE_7;
            } else if (TYPE05.fileTypeName.equals(fileTypeName)) {
                return CustomerAttachmentTypeEnum.TYPE_3;
            } else if (TYPE06.fileTypeName.equals(fileTypeName)) {
                return CustomerAttachmentTypeEnum.TYPE_2;
            }
            return null;
        }
    }


}

